package com.syh.jn.scm.infrastructure.repository.impl.operation.system;

import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.jn.scm.domain.operation.entity.system.OperationMenu;
import com.syh.jn.scm.domain.operation.entity.system.OperationRole;
import com.syh.jn.scm.domain.operation.repository.system.OperationRoleRepository;
import com.syh.jn.scm.dto.operation.system.menu.OperaMenuVo;
import com.syh.jn.scm.dto.operation.system.permission.PermissionVo;
import com.syh.jn.scm.dto.operation.system.role.OperationRoleVo;
import com.syh.jn.scm.infrastructure.repository.model.system.RoleMenuModel;
import com.syh.jn.scm.infrastructure.repository.model.system.RoleModel;
import com.syh.jn.scm.infrastructure.repository.utils.MybatisTemplate;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.hibernate.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public class OperationRoleRepositoryImpl extends AbstractAggregateRepository<OperationRole, RoleModel, Long> implements OperationRoleRepository {


  /**
   * @param operationRole
   * @param updateMenus
   */
  @Override
  public void update(OperationRole operationRole, Boolean updateMenus) {
    this.update(operationRole);
    if (updateMenus) {
      // 删除旧权限
      String hql = "delete RoleMenuModel model where model.roleId = :roleId";
      Query query = this.buildQuery(hql);
      query.setLong("roleId", operationRole.getId());
      query.executeUpdate();

      for (OperationMenu operationMenu : operationRole.getOperationMenuList()) {
        RoleMenuModel roleMenuModel = RoleMenuModel.builder().roleId(operationRole.getId()).menuId(operationMenu.getId()).menuCatalogId(operationMenu.getCatalogCode()).build();
        this.hibernateTemplate.save(roleMenuModel);
      }
    }
  }

  /**
   * 获取角色所有的权限
   *
   * @return
   */
  @Override
  public List<OperaMenuVo> getMenusByRoleId(Long roleId) {
    ExtAssert.notNull(roleId, "roleId 不可为空");
    SQL sql = new SQL() {{
      SELECT("menu.*");
      FROM("T_SYSTEM_ROLE_MENU roleMenu");
      LEFT_OUTER_JOIN("T_SYSTEM_MENU menu ON roleMenu.MENU_ID = menu.ID");
      WHERE("roleMenu.ROLE_ID = " + roleId,
              "menu.TYPE in (1,2)");
      ORDER_BY("menu.ORDER_LEVEL DESC ");
    }};
    List<Map<String, Object>> list = MybatisTemplate.selectList(sql.toString());
    return JSONArray.parseArray(JSONObject.toJSONString(list), OperaMenuVo.class);
  }

  /**
   * @param wrapper
   * @return
   */
  @Override
  public List<OperaMenuVo> getRoleMenusByWrapper(Wrapper wrapper) {
    SQL sql = new SQL() {{
      SELECT("menu.*");
      SELECT("roleMenu.ROLE_ID as roleId");
      SELECT("roleMenu.MENU_CATALOG_ID as menuCatalogId");
      FROM("T_SYSTEM_ROLE_MENU roleMenu");
      LEFT_OUTER_JOIN("T_SYSTEM_MENU menu ON roleMenu.MENU_ID = menu.ID");
    }};

    StringBuffer sqlString = new StringBuffer(sql.toString());
    BaseResolve resolveToSQL = new ResolveToSQL(wrapper);
    sqlString.append(" WHERE 1=1 ");
    sqlString.append(resolveToSQL.resolve());

    List<Map<String, Object>> list = MybatisTemplate.selectList(sqlString.toString());
    return JSONArray.parseArray(JSONObject.toJSONString(list), OperaMenuVo.class);
  }

  @Override
  protected Class getViewObject() {
    return OperationRoleVo.class;
  }

  @Override
  public List<PermissionVo> getPermissionByRoleId(Long roleId) {
    ExtAssert.notNull(roleId, "roleId 不可为空");
    SQL sql = new SQL() {{
      SELECT("per.*");
      FROM("T_SYSTEM_ROLE role");
      INNER_JOIN("T_SYSTEM_ROLE_MENU merel ON role.ID = merel.ROLE_ID");
      INNER_JOIN("T_SYSTEM_MENU_PERMISSION perel ON merel.MENU_ID=perel.MENU_ID");
      INNER_JOIN("T_SYSTEM_PERMISSION per ON perel.PERMISSION_ID=per.ID");
      WHERE("role.ID = " + roleId);
    }};
    List<Map<String, Object>> list = MybatisTemplate.selectList(sql.toString());
    return JSONArray.parseArray(JSONObject.toJSONString(list), PermissionVo.class);
  }

  /**
   * 获取角色菜单拥有的按钮
   *
   * @param roleId
   */
  @Override
  public List<OperaMenuVo> getMenusButtonByRoleId(Long roleId) {
    ExtAssert.notNull(roleId, "roleId 不可为空");
    SQL sql = new SQL() {{
      SELECT("menu.*");
      FROM("T_SYSTEM_ROLE_MENU roleMenu");
      LEFT_OUTER_JOIN("T_SYSTEM_MENU menu ON roleMenu.MENU_ID = menu.ID");
      WHERE("roleMenu.ROLE_ID = " + roleId,
              "menu.TYPE = 3");
      ORDER_BY("menu.ORDER_LEVEL DESC ");
    }};
    List<Map<String, Object>> list = MybatisTemplate.selectList(sql.toString());
    return JSONArray.parseArray(JSONObject.toJSONString(list), OperaMenuVo.class);
  }

  /**
   * 获取角色所有的权限
   *
   * @return
   */
  @Override
  public List<OperationRoleVo> getAllRolesWithPermission() {
    return null;
  }

  /**
   * 根据权限查找角色
   *
   * @param perId
   * @return
   */
  @Override
  public List<OperationRole> getRolesByPermissionId(Long perId) {
    return null;
  }


}
